#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>

int main()
{
  pid_t id = fork();

  if(id == 0)
  {
    //child
    int cnt = 5;
    while(cnt)
    {
      printf("我是子进程:%d, 我的父进程:%d, 距离死亡还有:%dS\n", getpid(), getppid(), cnt--);
      sleep(1);
      
      //int a = 10;
      //a /= 0;//导致退出异常，退出信号不为0
    }
    exit(123);//假设退出码为123
  }
  //parent
  
   // sleep(10);//5秒之后回收子进程，在此期间子进程的状态是僵尸状态,父进程一直处于阻塞状态S
  //pid_t ret = wait(NULL);//不关心子进程的退出状态的话，参数就为NULL
  //wait的成功返回子进程的pid,失败返回-1;
  //int statue = 0;
  //pid_t ret = waitpid(id, &statue, 0);
  //第三个参数为0时，waitpid进行的是阻塞等待，成功返回子进程的pid，失败返回-1
  //第一个参数是-1，那就是等待任意一个子进程进入Z
  //第一个参数也可以是指定的子进程的pid
  //第二个参数会返回子进程的返回状态，通过位图结构可以得到子进程对应的退出码和退出信号
  //退出信号为0，表示正常退出，退出码关乎的是结果的正确性

      
  //第三个参数位WNOHANG的时候，表示的waitpid为非阻塞等待，采用非阻塞轮询的方式等待waitpid返回结果
  //此时的返回值又多了一个--0 表示的是子进程还在执行中

  
  while(1)
  {
    int statue = 0;
    pid_t ret = waitpid(id, &statue, WNOHANG);
    
    if(ret == 0)
    {
      printf("子进程还在运行!\n");
    }
    else
    {  
       printf("父进程:%d, waitpid的返回结果:%d, 子进程退出码:%d, 子进程退出信号:%d\n",\
           getpid(), ret, (statue>>8)&0xFF, (statue)&0x7F); 

       break;
    }
    sleep(1);
  }
  //printf("父进程:%d, wait的返回结果:%d\n", getpid(), ret);
  //statue的前16位不用，次低8位表示的是退出码(判断退出的结果是否正确), 低7位是退出信号，信号不为0的时候，表示的是异常退出，此时的退出码就没有意义了，第8个bite位表示的是core_dump后面学！
  
  sleep(5);//三秒后父进程结束
  
  return 0;
}
